<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>ServiceStack Examples :: Ajax Client</title>

    <link rel="stylesheet" type="text/css" href="default.css" />

    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="js/ServiceStack.js"></script>

    <script type="text/javascript">
    <!--
        //Get the hostName of this page

        //Create a ClientGateway passing in the baseUrl where your services are hosted.
        //Note: services not on the same domain require a crossdomain.xml policy
        var gateway = new servicestack.ClientGateway(
            'http://localhost:64067/ServiceStack/');

        $(function()
        {

            $("#btnGetFactorial").click(function()
            {
                gateway.getFromService({
                        GetFactorial: { ForNumber: $("#txtGetFactorial").val() }
                    },
                    function(e) {
                        $("#serviceGetFactorial .result").html(e.Result);
                    });
            });

            $("#btnGetFibonacciNumbers").click(function()
            {
                gateway.getFromService({
                    GetFibonacciNumbers: {
                        Skip: $("#txtGetFibonacciNumbersSkip").val(),
                        Take: $("#txtGetFibonacciNumbersTake").val()
                    }
                }, function(e)
                {
                    var resultHtml = "<ul>";
                    $(e.Results).each(function(i, fibNo)
                    {
                        resultHtml += "<li>" + fibNo + "</li>";
                    });
                    resultHtml += "</ul>";

                    $("#serviceGetFibonacciNumbers .result").html(resultHtml);
                });
            });

            $("#btnStoreNewUser").click(function()
            {
                gateway.postToService({
                    StoreNewUser: {
                        UserName: $("#txtUserName").val(),
                        Password: $("#txtUserName").val(),
                        Email: $("#txtEmail").val()
                    }
                }, function(e)
                {
                    $("#serviceStoreNewUser .result").html(e.UserId);

                    var userIds = $("#txtUserIds").val();
                    if (userIds.length > 0) userIds += ",";
                    $("#txtUserIds").val(userIds + e.UserId);
                },
                function(ex)
                {
                    alert("Error creating new User:\n" + ex.message);
                });
            });

            $("#btnDeleteAllUsers").click(function()
            {
                gateway.postToService("DeleteAllUsers",
                    function(e) {
                        alert('All Users were deleted');
                        $("#txtUserIds").val("");
                    },
                    function(ex) {
                        alert('Error deleting all users: ' + ex.message);
                    });
            });

            $("#btnGetUsers").click(function()
            {
                gateway.getFromService({
                        GetUsers: { UserIds: $("#txtUserIds").val() }
                    },
                    function(e) {
                        var resultHtml = "";
                        $(e.Users).each(function(i, user)
                        {
                            resultHtml += '<div class="user">'
                                + user.UserName + "<br />"
                                + user.Email
                                + "</div>";
                        });
                        $("#serviceGetUsers .result").html(resultHtml);
                    });
            });

            $(".code-link SPAN").click(function()
            {
                var link = $(this);
                var codePreview = link.next();
                if (codePreview.is(":visible"))
                {
                    codePreview.slideUp(function()
                    {
                        link.html("show");
                    });
                }
                else
                {
                    $(".code-preview").hide();
                    $(".code-link SPAN").html("show");
                    codePreview.fadeIn(function()
                    {
                        link.html("hide");
                    });
                }
            });

        });
    -->
    </script>

</head>
<body>

    <div id="header-links">
        <a href="../ServiceStack.Hello/">Hello World</a>
        <a href="../Backbone.Todos/">Todos</a>
        <a href="../RedisStackOverflow/">Redis StackOverflow</a>
        <a href="../RestFiles/">REST Files</a>
        <a href="../ServiceStack.MovieRest/">REST Movies</a>
        <a href="../ServiceStack.Northwind/">Northwind Database</a>
        <a href="../ServiceStack.Examples.Clients/">Ajax Client</a>
    </div>

    <a href="http://mono.servicestack.net"><img src="img/demo-logo-servicestack.png" alt="Service Stack Demo" /></a>

    <h1>Calling ServiceStack Web Services with Ajax</h1>

    <p>
        For performance reasons, the preferred to call ServiceStack services for Ajax clients
        is using JSON via the JSON endpoint at: <br />
        <em>~/servicestack/json/reply/{ServiceName}</em>
    </p>
    <p>
        As this endpoint is just a standard JSON service we can use any ajax client to call them with.
        In this example we're using a light-wrapper around jQuery's $.ajax client.
    </p>

    <h4>1. First step is to initialize the ServiceClient</h4>
    <code>
        //Create a ClientGateway passing in the baseUrl where your services are hosted.
        var gateway = new servicestack.ClientGateway(
                location.protocol + "//" + location.host + '/ServiceStack.Examples.Host.Web/ServiceStack/');
    </code>

    <h4>2. After that calling a service becomes as easy as:</h4>
    <code>
        gateway.getFromService({
                GetFactorial: { ForNumber: $("#txtGetFactorial").val() }
            },
            function(e) {
                $("#serviceGetFactorial .result").html(e.Result);
            });
    </code>

    <h4>3. Try the live examples yourself:</h4>
    <div id="services">
        <div id="serviceGetFactorial" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    gateway.getFromService({
            GetFactorial: { ForNumber: $("#txtGetFactorial").val() }
        },
        function(e) {
            $("#serviceGetFactorial .result").html(e.Result);
        });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    public class GetFactorial
    {
        public long ForNumber { get; set; }
    }

    public class GetFactorialResponse
    {
        public long Result { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class GetFactorialService : IService&lt;GetFactorial&gt;
    {
        public object Execute(GetFactorial request)
        {
            return new GetFactorialResponse { Result = GetFactorial(request.ForNumber) };
        }

        static long GetFactorial(long n)
        {
            return n &gt; 1 ? n * GetFactorial(n - 1) : 1;
        }
    }
                        </code>
                    </div>
                </div>

            <div class="input">
                <h3>Get Factorial Service</h3>
                <label>For Number:</label>
                <input class="int" type="text" id="txtGetFactorial" value="3" />
                <button id="btnGetFactorial">Go</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>
        </div>

        <div id="serviceGetFibonacciNumbers" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    gateway.getFromService({
            GetFibonacciNumbers: {
                Skip: $("#txtGetFibonacciNumbersSkip").val(),
                Take: $("#txtGetFibonacciNumbersTake").val()
            }
        },
        function(e) {
            var resultHtml = "&lt;ul&gt;";
            $(e.Results).each(function(i, fibNo)
            {
                resultHtml += "&lt;li&gt;" + fibNo + "&lt;/li&gt;";
            });
            resultHtml += "&lt;/ul&gt;";

            $("#serviceGetFibonacciNumbers .result").html(resultHtml);
        });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    public class GetFibonacciNumbers
    {
        public long? Skip { get; set; }

        public long? Take { get; set; }
    }

    public class GetFibonacciNumbersResponse
    {
        public ArrayOfLong Results { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class GetFibonacciNumbersService
        : IService&lt;GetFibonacciNumbers&gt;
    {
        private readonly ExampleConfig config;

        //Example of ServiceStack's built-in Funq IOC constructor injection
        public GetFibonacciNumbersService(ExampleConfig config)
        {
            this.config = config;
        }

        public object Execute(GetFibonacciNumbers request)
        {
            var skip = request.Skip.GetValueOrDefault(0);
            var take = request.Take.GetValueOrDefault(config.DefaultFibonacciLimit);

            var results = new List&lt;long&gt;();

            var i = 0;
            foreach (var fibonacciNumber in GetFibonacciNumbersNumbers())
            {
                if (i++ &lt; skip) continue;

                results.Add(fibonacciNumber);

                if (results.Count == take) break;
            }

            return new GetFibonacciNumbersResponse { Results = new ArrayOfLong(results) };
        }

        static IEnumerable&lt;long&gt; GetFibonacciNumbersNumbers()
        {
            long n1 = 0;
            long n2 = 1;

            while (true)
            {
                var n3 = n1 + n2;
                yield return n3;
                n1 = n2;
                n2 = n3;
            }
        }
    }
                        </code>
                    </div>
                </div>

            <div class="input">

                <h3>Get Fibonacci Numbers Service</h3>

                <label>Skip:</label>
                <input class="int" type="text" id="txtGetFibonacciNumbersSkip" value="3" />

                <label>Take:</label>
                <input class="int" type="text" id="txtGetFibonacciNumbersTake" value="10" />

                <button id="btnGetFibonacciNumbers">Go</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>
        </div>

        <div id="serviceStoreNewUser" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    gateway.postToService({
            StoreNewUser: {
                UserName: $("#txtUserName").val(),
                Password: $("#txtUserName").val(),
                Email: $("#txtEmail").val()
            }
        },
        function(e) {
            $("#serviceStoreNewUser .result").html(e.UserId);

            var userIds = $("#txtUserIds").val();
            if (userIds.length > 0) userIds += ",";
            $("#txtUserIds").val(userIds + e.UserId);
        },
        function(ex) {
            alert("Error creating new User: " + ex);
        });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    public class StoreNewUser
    {
        public string UserName { get; set; }

        public string Email { get; set; }

        public string Password { get; set; }
    }

    public class StoreNewUserResponse
    {
        public StoreNewUserResponse()
        {
            this.ResponseStatus = new ResponseStatus();
        }

        public long UserId { get; set; }

        public ResponseStatus ResponseStatus { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class StoreNewUserService : IService&lt;StoreNewUser&gt;
    {
        //Example of ServiceStack's built-in Funq IOC property injection
        public IDbConnectionFactory ConnectionFactory { get; set; }

        public object Execute(StoreNewUser request)
        {
            using (var dbConn = ConnectionFactory.OpenDbConnection())
            using (var dbCmd = dbConn.CreateCommand())
            {
                var existingUsers = dbCmd.Select&lt;User&gt;("UserName = {0}",
                  request.UserName).ToList();

                if (existingUsers.Count &gt; 0)
                {
                    return new StoreNewUserResponse {
                        ResponseStatus = new ResponseStatus {
                          ErrorCode = "UserNameMustBeUnique"
                        }
                    };
                }

                var newUser = new User {
                    UserName = request.UserName,
                    Email = request.Email,
                    Password = request.Password
                };

                dbCmd.Insert(newUser);

                return new StoreNewUserResponse { UserId = dbCmd.GetLastInsertId() };
            }
        }
    }
                        </code>
                    </div>
                </div>

            <div class="input">
                <h3>Store New User Service</h3>

                <div class="form">
                    <label>User Name:</label>
                    <input type="text" id="txtUserName" value="User 1" />

                    <label>Password:</label>
                    <input type="text" id="txtPassword" value="password" />

                    <label>Email:</label>
                    <input type="text" id="txtEmail" value="as@if.com" />
                </div>

                <button id="btnStoreNewUser">Create New User</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>

            <button id="btnDeleteAllUsers">Delete All Users</button>
        </div>

        <div id="serviceGetUsers" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    gateway.getFromService({
            GetUsers: { UserIds: $("#txtUserIds").val() }
        },
        function(e) {
            var resultHtml = "&lt;div&gt;";
            $(e.Users).each(function(i, user)
            {
                resultHtml += '&lt;div class="user"&gt;'
                + user.UserName + "&lt;br /&gt;"
                + user.Email
                + "&lt;/div&gt;";
            });
            $("#serviceGetUsers .result").html(resultHtml);
        });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    public class GetUsers
    {
        public ArrayOfLong UserIds { get; set; }

        public ArrayOfString UserNames { get; set; }
    }

    public class GetUsersResponse
    {
        public GetUsersResponse()
        {
            this.ResponseStatus = new ResponseStatus();
        }

        public ArrayOfUser Users { get; set; }

        public ResponseStatus ResponseStatus { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class GetUsersService : IService&lt;GetUsers&gt;
    {
        //Example of ServiceStack's built-in Funq IOC property injection
        public IDbConnectionFactory ConnectionFactory { get; set; }

        public object Execute(GetUsers request)
        {
            using (var dbConn = ConnectionFactory.OpenDbConnection())
            using (var dbCmd = dbConn.CreateCommand())
            {
                var users = new List&lt;User&gt;();

                if (request.UserIds != null &amp;&amp; request.UserIds.Count &gt; 0)
                {
                    users.AddRange(dbCmd.GetByIds&lt;User&gt;(request.UserIds));
                }

                if (request.UserNames != null &amp;&amp; request.UserNames.Count &gt; 0)
                {
                    users.AddRange(dbCmd.Select&lt;User&gt;(
                        "UserName IN ({0})", request.UserNames.SqlInValues()));
                }

                return new GetUsersResponse { Users = new ArrayOfUser(users) };
            }
        }
    }
                        </code>
                    </div>
                </div>

            <div class="input">
                <h3>Get Users Service</h3>

                <div class="form">
                    <label>User Ids:</label>
                    <input type="text" id="txtUserIds" value="" />
                </div>

                <button id="btnGetUsers">Get Users</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>
        </div>

        <span class="r"></span>
    </div>

    <h4>4. Check out the other ways to call your services</h4>
    <p>
        One of the nice things about ServiceStack is that by using <acronym title="Plain Old CSharp Objects">POCO</acronym> classes to define your Service Interface
        we're able to seperate the 'message' (payload) from the communication 'channel' that delivers it.
    </p>
    <p>
        This means that calling your services using XML is as easy as sending your request to a different end point.
        So calling your service via XML is as easy as:
        <ol>
            <li><a href="/ServiceStack.Examples.Host.Web/servicestack/xml/reply/GetFactorial?ForNumber=3" target="_blank">
                servicestack/xml/reply/GetFactorial?ForNumber=3</a>
            </li>
            <li><a href="/ServiceStack.Examples.Host.Web/servicestack/xml/reply/GetFibonacciNumbers?Skip=3&Take=20" target="_blank">
                servicestack/xml/reply/GetFibonacciNumbers?Skip=3&Take=20</a>
            </li>
        </ol>
        <br />
        Out of the box ServiceStack provides REST+JSON, REST+XML and <acronym title="Plain Old XML">POX</acronym>, SOAP 1.1 and SOAP 1.2 end points.
    </p>
    <p>
        The dynamic <a href="/ServiceStack.Examples.Host.Web/ServiceStack/Metadata">metadata summary page</a>
        has a complete list of web services and end points that are available.<br />
    </p>

    <h4>5. View the source code online or Download:</h4>
    <p>
        The complete source code for this example is
        <a href="https://github.com/ServiceStack/ServiceStack.Examples/tree/master/src/ServiceStack.Examples/ServiceStack.Examples.Clients/">
            viewable online
        </a>
        or available to download as zip package from the link below:

        <a id="btn-download" href="https://github.com/ServiceStack/ServiceStack.Examples/downloads">
            <img src="http://mono.servicestack.net/btn-download.gif" alt="Download ServiceStack.Examples.zip">
        </a>
    </p>


    <div id="footer-links">
        <a href="http://mono-project.com/">
            <img src="img/Mono-powered-big.png" alt="powered by mono" />
        </a>

        <a href="http://www.ajaxstack.com">Ajax Stack</a> |
        <a href="http://mono.servicestack.net">Service Stack</a>

    </div>

<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-7722718-7']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
</script>
</body>
</html>
